4 // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
6 // The use and distribution terms for this software are contained in the file
7 // named license.txt, which can be found in the root of this distribution.
8 // By using this software in any fashion, you are agreeing to be bound by the
9 // terms of this license.
11 // You must not remove this notice, or any other, from this software.
16 namespace Microsoft
.JScript
{
19 using System
.Collections
;
20 using System
.Reflection
;
21 using System
.Reflection
.Emit
;
23 internal sealed class DoWhile
: AST
{
25 private AST condition
;
26 private Completion completion
;
28 internal DoWhile(Context context
, AST body
, AST condition
)
31 this.condition
= condition
;
32 this.completion
= new Completion();
35 internal override Object
Evaluate(){
36 this.completion
.Continue
= 0;
37 this.completion
.Exit
= 0;
38 this.completion
.value = null;
40 Completion c
= (Completion
)this.body
.Evaluate();
42 this.completion
.value = c
.value;
44 this.completion
.Continue
= c
.Continue
- 1;
48 this.completion
.Exit
= c
.Exit
- 1;
53 }while (Convert
.ToBoolean(this.condition
.Evaluate()) == true);
54 return this.completion
;
57 internal override AST
PartiallyEvaluate(){
58 ScriptObject current_scope
= Globals
.ScopeStack
.Peek();
59 while (current_scope
is WithObject
) current_scope
= current_scope
.GetParent();
60 if (current_scope
is FunctionScope
){
61 FunctionScope scope
= (FunctionScope
)current_scope
;
62 BitArray before
= scope
.DefinedFlags
;
63 this.body
= this.body
.PartiallyEvaluate();
64 scope
.DefinedFlags
= before
; //The body may have a continue in it
65 this.condition
= this.condition
.PartiallyEvaluate();
66 scope
.DefinedFlags
= before
;
67 //This is very pessimistic, but the potential presence of break/continue/return/throw
68 //inside the loop presents complications that are hard to resolve naively.
70 this.body
= this.body
.PartiallyEvaluate();
71 this.condition
= this.condition
.PartiallyEvaluate();
73 IReflect conditiontype
= this.condition
.InferType(null);
74 if (conditiontype
is FunctionPrototype
|| conditiontype
== Typeob
.ScriptFunction
)
75 this.context
.HandleError(JSError
.SuspectLoopCondition
);
79 internal override void TranslateToIL(ILGenerator il
, Type rtype
){
80 //This assumes that rtype == Void.class
81 Label loop_start
= il
.DefineLabel();
82 Label condition_start
= il
.DefineLabel();
83 Label loop_end
= il
.DefineLabel();
84 compilerGlobals
.BreakLabelStack
.Push(loop_end
);
85 compilerGlobals
.ContinueLabelStack
.Push(condition_start
);
86 il
.MarkLabel(loop_start
);
87 this.body
.TranslateToIL(il
, Typeob
.Void
);
88 il
.MarkLabel(condition_start
);
89 this.context
.EmitLineInfo(il
);
90 this.condition
.TranslateToConditionalBranch(il
, true, loop_start
, false);
91 il
.MarkLabel(loop_end
);
92 compilerGlobals
.BreakLabelStack
.Pop();
93 compilerGlobals
.ContinueLabelStack
.Pop();
96 internal override void TranslateToILInitializer(ILGenerator il
){
97 this.body
.TranslateToILInitializer(il
);
98 this.condition
.TranslateToILInitializer(il
);
101 internal override Context
GetFirstExecutableContext(){
102 return this.body
.GetFirstExecutableContext();